<template>
  <div v-loading="saveLoading || getTemplateDetailLoading" element-loading-text="加载中...">
    <div class="app-container">
      <div class="app-container-inner">
        <div style="display: flex; justify-content: space-between; align-items: center">
          <el-form ref="moduleFormRef" :rules="moduleRules" :model="moduleForm" :inline="true">
            <!-- 模版名称 -->
            <el-form-item label="模版名称" prop="name">
              <el-input v-model="moduleForm.name" clearable placeholder="请输入名称" />
            </el-form-item>

            <!-- 应用工单模块 -->
            <el-form-item label="应用工单模块" label-width="100">
              <el-select
                v-model="moduleIds"
                style="width: 350px"
                placeholder="请选择工单模块"
                multiple
                collapse-tags
                collapse-tags-tooltip
                filterable
                clearable
                reserve-keyword
                remote-show-suffix
                :loading="getModuleOptionsLoading"
                :filter-method="handleGetModuleOptions"
              >
                <el-option
                  v-for="item in moduleOptions"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>

            <!-- 按钮组 -->
            <el-form-item label="">
              <div style="display: flex; align-items: center; gap: 7px">
                <el-switch
                  v-model="moduleForm.status"
                  :active-value="false"
                  :inactive-value="true"
                  class="status"
                />
                <span v-if="moduleForm.status">禁用</span>
                <span v-else>启用</span>
              </div>
            </el-form-item>
          </el-form>
          <div style="display: flex; align-items: center; gap: 5px">
            <HPlainButton @click="saveTemplate(moduleFormRef)"> 保存 </HPlainButton>
            <HButton @click="backList"> 取消 </HButton>
            <HPlainButton type="error" @click="deleteTemplate"> 删除 </HPlainButton>
          </div>
        </div>
      </div>
    </div>
    <el-container>
      <el-main>
        <div class="app-container">
          <div class="app-container-inner">
            <div class="header-field flex-justify-between">
              <div class="title flex-align-center">
                结单自定义字段
                <span>(可拖动字段进行排序)</span>
              </div>
              <div style="display: flex; align-items: center; gap: 5px">
                <HPlainButton @click="addField"> 添加字段 </HPlainButton>
                <el-dropdown trigger="click">
                  <HButton :disabled="selecttion.length === 0">
                    批量操作
                    <el-icon class="el-icon--right">
                      <ArrowDown />
                    </el-icon>
                  </HButton>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item @click="changeStatus(1)">
                        <el-icon> <CircleCheck /> </el-icon>批量启用
                      </el-dropdown-item>
                      <el-dropdown-item @click="changeStatus(2)">
                        <el-icon> <Warning /> </el-icon>批量禁用
                      </el-dropdown-item>
                      <el-dropdown-item @click="changeStatus(3)">
                        <el-icon> <Delete /> </el-icon>批量删除
                      </el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
            </div>
            <el-divider />
            <div class="field-list">
              <el-table
                border
                stripe
                resizable
                @selection-change="handleChange"
                :data="tableData"
                ref="tableDom"
              >
                <!--选择框-->
                <el-table-column show-overflow-tooltip type="selection" width="40" fixed="left" />

                <!--字段名称-->
                <el-table-column show-overflow-tooltip prop="name" label="字段名称" width="200" />

                <!--状态-->
                <el-table-column show-overflow-tooltip prop="status" label="状态" width="70">
                  <template #default="scope">
                    <HStatus v-if="!scope.row.status">启用</HStatus>
                    <HStatus v-if="scope.row.status" type="info">禁用</HStatus>
                  </template>
                </el-table-column>

                <!--字段类型-->
                <el-table-column show-overflow-tooltip label="字段类型" width="75">
                  <template #default="scope">
                    <span
                      v-for="item in fieldTypeOptions"
                      :key="item.val"
                      v-show="scope.row.type == item.val"
                      >{{ item.name }}</span
                    >
                  </template>
                </el-table-column>

                <!--字段内容-->
                <el-table-column prop="content" label="字段内容" min-width="200" />

                <!--提示信息-->
                <el-table-column prop="tip" label="提示信息" width="150" />

                <!--最大尺寸(MB)-->
                <el-table-column prop="uploadSize" label="最大尺寸(MB)" width="110">
                  <template v-slot="i">
                    <span v-if="i.row.type == 5 || i.row.type == 6 || i.row.type == 7">{{
                      i.row.uploadSize
                    }}</span>
                    <span v-else></span>
                  </template>
                </el-table-column>

                <!--上传数量-->
                <el-table-column prop="uploadQty" label="上传数量" width="75">
                  <template v-slot="i">
                    <span v-if="i.row.type == 5 || i.row.type == 6 || i.row.type == 7">{{
                      i.row.uploadQty
                    }}</span>
                    <span v-else></span>
                  </template>
                </el-table-column>

                <!--是否必填-->
                <el-table-column prop="required" label="是否必填" width="80">
                  <template #default="scope">
                    <span v-if="scope.row.required">必填</span>
                    <span v-if="!scope.row.required">选填</span>
                  </template>
                </el-table-column>

                <!--排序-->
                <!-- <el-table-column prop="sort" label="排序" width="80" sortable /> -->

                <!--操作-->
                <el-table-column fixed="right" label="操作" width="120">
                  <template #default="scope">
                    <div class="btns flex-justify-between">
                      <el-icon class="edit" @click="editField(scope.row, scope.$index)">
                        <Edit />
                      </el-icon>
                      <el-icon class="dele" @click="deleteField(scope.row, scope.$index)">
                        <Delete />
                      </el-icon>
                      <el-icon title="置顶" @click="topField(scope.$index)">
                        <Top />
                      </el-icon>
                      <i class="fa fa-bars move" title="拖动" @mousedown="fieldSort($event, scope.$index)" />
                    </div>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </div>
      </el-main>
      <el-aside width="440px">
        <div class="aside-temp">
          <div class="title">结单模版</div>
          <p class="tip"
            >申请结单时，将按照此模版上传结单信息，<span style="font-weight: bold"
              >此处仅是预览字段和模版</span
            >；</p
          >
          <el-form label-width="80" class="form-data">
            <!-- 故障内容 -->
            <el-form-item label="故障内容" class="form-item" required>
              <el-input clearable class="text-input" disabled />
            </el-form-item>

            <!-- 故障内容 -->
            <el-form-item label="故障内容" class="form-item" required>
              <el-input clearable class="text-input" disabled />
            </el-form-item>
          </el-form>
        </div>
      </el-aside>
    </el-container>

    <AddOrUpdateFieldModal
      v-model="addOrUpdateFieldModalValue.modalVisible"
      :form="addOrUpdateFieldModalValue.form"
      :is-add="addOrUpdateFieldModalValue.isAdd"
      :modal-title="addOrUpdateFieldModalValue.title"
      @updated="handleUpdateField"
    />
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, markRaw, onMounted, watch } from 'vue'
  import type { Action, FormInstance, MessageBoxState } from 'element-plus'
  import { ElMessage, ElMessageBox } from 'element-plus'
  import { Delete, Warning, Top, Edit, CircleCheck, ArrowDown } from '@element-plus/icons-vue'
  import { useTagsViewStore } from '@/store/modules/tagsView'
  import { useRoute, useRouter } from 'vue-router'
  import {
    visitTmpDelete,
    deleteVisitModuleField,
    disableVisitModuleField,
    getVisitFieldDetail,
  } from '@/api/basic'
  import _ from 'lodash'
  import { useGetModuleOptions, useForm } from './services'
  import AddOrUpdateFieldModal from './components/AddOrUpdateFieldModal.vue'
  import { AddOrUpdateFieldModalValue, FieldForm, FieldTableData } from './types'
  import HPlainButton from '@/components/common/button/HPlainButton.vue'
  import HButton from '@/components/common/button/HButton.vue'
  import HStatus from '@/components/common/status/HStatus.vue'
  import pageComponentName from '@/config/page-component-name'

  defineOptions({
    name: pageComponentName.setting.followUpEemplateFormSet,
  })

  // 字段类型下拉选项
  const fieldTypeOptions = ref([
    { name: '文本', val: 1 },
    { name: '多行文本', val: 2 },
    { name: '单选', val: 3 },
    { name: '多选', val: 4 },
    { name: '多图', val: 5 },
    { name: '附件', val: 6 },
    { name: '视频', val: 7 },
    { name: '评分', val: 8 },
  ])

  const TagsViewStore = useTagsViewStore()
  const route = useRoute()
  const router = useRouter()

  const moduleIds = ref([])
  const moduleTmpIds = ref([])

  // 使用表单服务
  const { form: moduleForm, saveLoading, saveFn, getFormFn } = useForm()

  // 验证规则
  const moduleRules = reactive({
    name: [{ required: true, message: '请输入模版名称', trigger: 'blur' }],
  })

  // 字段列表数据
  const tableData = ref<Array<FieldTableData>>([])

  // 字段列表组件实例
  const tableDom = ref()

  // 模块表单组件实例
  const moduleFormRef = ref<FormInstance>()

  // 使用获取模块下拉选项服务
  const { getModuleOptionsFn, getModuleOptionsLoading, moduleOptions } = useGetModuleOptions

  // 获取工单模块关键字
  const getModuleOptionsKeyword = ref('')

  /**
   * 获取工单模块下拉选
   */
  const handleGetModuleOptions = _.throttle((query: string) => {
    if (getModuleOptionsKeyword.value !== query) {
      getModuleOptionsKeyword.value = query
      getModuleOptionsFn(getModuleOptionsKeyword.value)
    }
  }, 500)

  // 字段弹窗相关的数据，包含：弹窗的标题、显示状态、是否为添加、字段表单
  const addOrUpdateFieldModalValue = ref<AddOrUpdateFieldModalValue>({
    modalVisible: false,
    title: '',
    isAdd: false,
    updateIndex: 0,
    form: {
      type: 1,
      contentVos: [
        {
          id: '',
          val: '',
        },
      ],
      delContentIds: [],
      id: null,
      uploadSize: 100,
      name: '',
      required: true,
      sort: 0,
      status: false,
      tip: '',
      uploadQty: 1,
      num: 0,
    },
  })

  /**
   * 添加字段
   */
  const addField = () => {
    tableData.value.length
    addOrUpdateFieldModalValue.value = {
      form: {
        type: 1,
        contentVos: [{ val: '', id: '' }],
        delContentIds: [],
        id: null,
        uploadSize: 100,
        name: '',
        required: true,
        sort: 0,
        status: false,
        tip: '',
        uploadQty: 1,
        num: tableData.value.length,
      },
      isAdd: true,
      title: '添加字段',
      modalVisible: true,
      updateIndex: 0,
    }
  }

  // 编辑字段加载
  const updateFieldLoading = ref(false)

  /**
   * 编辑字段
   * @param {object} obj - 字段对象
   * @param {number} index - 操作的表格行的索引
   */
  const editField = async (obj: FieldForm, index: number) => {
    updateFieldLoading.value = false
    addOrUpdateFieldModalValue.value = {
      form: _.cloneDeep(obj),
      isAdd: false,
      updateIndex: index,
      title: '编辑字段',
      modalVisible: true,
    }
  }

  /**
   * 添加或编辑字段弹窗保存事件
   * @param {object} param - 字段对象
   */
  const handleUpdateField = (param: FieldForm) => {
    /**
     * 修改字段表单，添加属性content，用于在表格上展示
     */
    let __fieldForm: FieldTableData = { ...param, content: [] }
    if ([3, 4].includes(param.type)) {
      __fieldForm = { ...param, content: param.contentVos.map((item) => item.val) }
    }
    if (addOrUpdateFieldModalValue.value.isAdd) {
      tableData.value.push(__fieldForm)
    } else {
      tableData.value[addOrUpdateFieldModalValue.value.updateIndex] = __fieldForm
    }

    /**
     * 将字段表单的数据更新到模块表单里
     */
    moduleForm.value.templateField = tableData.value.map((item) => {
      const __field = { ...item }
      delete __field.content
      return __field
    })

    /**
     * 重置字段表单
     */
    addOrUpdateFieldModalValue.value = {
      form: {
        type: 1,
        contentVos: [{ val: '', id: '' }],
        delContentIds: [],
        id: null,
        uploadSize: 100,
        name: '',
        required: true,
        sort: 0,
        status: false,
        tip: '',
        uploadQty: 1,
        num: 0,
      },
      isAdd: false,
      title: '',
      modalVisible: false,
      updateIndex: 0,
    }
  }

  /**
   * 删除字段
   * @param {object} obj - 字段对象
   */
  const deleteField = (obj: FieldForm, index = null) => {
    changeMethod('删除', disableVisitModuleField, [obj.num], 3)
  }

  // 置顶字段
  const topField = (i: number) => {
    moduleForm.value.templateField[i].sort = 0
    tableData.value[i].sort = 0
    let changeItem = tableData.value[i] // 置顶的项
    tableData.value.splice(i, 1)
    tableData.value.unshift(changeItem)
  }

  // 拖动字段排序
  const fieldSort = (obj, key: number) => {
    obj.preventDefault()
    let index
    tableData.value.forEach((item, i) => {
      if (i == key) {
        index = i
      }
    })
    let changeItem = tableData.value[index] // 移动的项
    let dom = obj.target
    //  算出鼠标相对元素的位置
    let reY = obj.clientY - dom.offsetTop
    //  鼠标按下事件，松开后不再移动
    document.onmouseup = (e) => {
      document.onmousemove = null
      document.onmouseup = null
      //  用鼠标的位置减去鼠标相对元素的位置，得到元素的位置
      let top = e.clientY - reY
      let num = Math.floor(top / 49) // 移动的位置
      if (num > 0) {
        // 下移
        tableData.value[index].sort = tableData.value[index + num].sort + 1
        tableData.value.splice(index, 1)
        tableData.value.splice(index + num, 0, changeItem)
        moduleForm.value.templateField[index].sort =
          moduleForm.value.templateField[index + num].sort + 1
      } else {
        // 上移
        num = Math.abs(num)
        tableData.value[index].sort = tableData.value[index - num].sort - 1
        tableData.value.splice(index, 1)
        tableData.value.splice(index - num, 0, changeItem)
        moduleForm.value.templateField[index].sort =
          moduleForm.value.templateField[index - num].sort - 1 < 0
            ? 0
            : moduleForm.value.templateField[index - num].sort - 1
      }
    }
  }

  // 返回列表
  const backList = () => {
    TagsViewStore.delView(route.path) // 关闭当前页面
    router.go(-1) // 返回列表页面
  }

  /**
   * 保存方法
   */
  const saveDataMethod = async () => {
    // 应用模版数据
    let tmp = []
    moduleForm.value.templateModuleIds.forEach((item) => {
      if (item.moduleId) {
        tmp.push(item.moduleId)
      }
    })
    if (moduleIds.value.length !== 0) {
      moduleIds.value.forEach((item) => {
        if (!tmp.includes(item)) {
          moduleForm.value.templateModuleIds.push({
            moduleId: item,
          })
        }
      })
    } else {
      moduleForm.value.templateModuleIds = []
    }

    const res = await saveFn()
    if (res.success == true) {
      ElMessage({
        message: res.message,
        type: 'success',
        duration: 2000,
      })

      /**
       * 重置模块表单
       * 不重置会导致表单被缓存，然后下一次添加就会带上一次添加的数据
       */
      moduleForm.value = {
        delTemplateModuleIds: [],
        id: null,
        name: '',
        status: false,
        templateField: [],
        templateModuleIds: [],
      }
      backList()
    } else {
      ElMessage({
        message: res.message,
        type: 'warning',
        duration: 2000,
      })
      return
    }
  }

  // 保存模版
  const saveTemplate = (formEl: FormInstance) => {
    formEl.validate((val) => {
      if (val) {
        if (moduleForm.value.templateField.length == 0) {
          ElMessage({
            message: '至少添加一个结单字段',
            type: 'warning',
            duration: 2000,
          })
          return
        }
        saveDataMethod()
      }
    })
  }

  // 删除模版
  const deleteTemplate = () => {
    ElMessageBox({
      type: 'error',
      title: '提示',
      icon: markRaw(Delete),
      message: `确认删除该模版?`,
      showCancelButton: true,
      closeOnClickModal: false,
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      autofocus: false,
      beforeClose: (action: Action, instance: MessageBoxState, done: () => void) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.confirmButtonText = '加载中...'
          setTimeout(() => {
            done()
            setTimeout(() => {
              instance.confirmButtonLoading = false
            }, 0)
          }, 1000)
        } else {
          done()
        }
      },
    }).then(async () => {
      const res = await visitTmpDelete([route.params.id])
      ElMessage({
        message: res.data.message,
        type: 'success',
        duration: 2000,
      })
      backList()
    })
  }

  // 获取模版详情加载
  const getTemplateDetailLoading = ref(false)

  /**
   * 获取模版详情
   */
  const getDetail = async () => {
    getTemplateDetailLoading.value = true
    moduleForm.value.templateModuleIds = []
    tableData.value = []
    await getFormFn(route.params.id as string)
    if (moduleForm.value.templateModuleIds.length !== 0) {
      moduleForm.value.templateModuleIds.forEach((item) => {
        moduleIds.value.push(item.moduleId)
        moduleTmpIds.value.push(item.moduleId)
      })
    }
    /**
     * 对字段进行处理
     * 1、先获取字段详情
     * 2、再将字段信息添加到字段列表里
     * 这种获取字段详情的处理方式不是很好，如果有多个字段就会导致页面一直在转圈，但是暂时只想到这种方式处理，等以后优化
     */
    if (moduleForm.value.templateField.length !== 0) {
      for (const templateFieldKey of moduleForm.value.templateField) {
        const res = await getVisitFieldDetail(templateFieldKey.id)
        let tmp = []
        if (res.data.data.row.contentVos.length !== 0) {
          res.data.data.row.contentVos.forEach((contentVo: { id: string; val: string }) => {
            tmp.push(contentVo.val)
          })
        }

        tableData.value.push({
          type: res.data.data.row.type,
          content: res.data.data.row.type === 4 || res.data.data.row.type === 3 ? tmp : [],
          contentVos: res.data.data.row.contentVos,
          delContentIds: res.data.data.row.delContentIds,
          id: res.data.data.row.id,
          uploadSize: res.data.data.row.uploadSize,
          name: res.data.data.row.name,
          required: res.data.data.row.required,
          sort: res.data.data.row.sort,
          status: res.data.data.row.status,
          tip: res.data.data.row.tip,
          uploadQty: res.data.data.row.uploadQty,
          num: tableData.value.length,
        })
      }
    }
    getTemplateDetailLoading.value = false
  }

  // 获取列表选中的数据
  const selecttion = ref<Array<string>>([])
  const handleChange = (val) => {
    if (val.length != 0) {
      val.forEach((item) => {
        if (selecttion.value.indexOf(item.id) == -1) {
          selecttion.value.push(item.num)
        } else {
          selecttion.value = selecttion.value.filter((i) => i == item.num)
        }
      })
    } else {
      selecttion.value = []
    }
  }

  // 修改状态方法
  const changeMethod = (type, method, arr, status) => {
    if (arr.length == 0) {
      ElMessage({
        message: `请选择要${type}的字段`,
        type: 'warning',
        duration: 2000,
      })
      return
    }
    ElMessageBox({
      type: type == '删除' ? 'error' : 'warning',
      title: '提示',
      icon: type == '删除' ? markRaw(Delete) : markRaw(Warning),
      message: `确认${type}选中的字段?`,
      showCancelButton: true,
      closeOnClickModal: false,
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      autofocus: false,
      beforeClose: (action: Action, instance: MessageBoxState, done: () => void) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.confirmButtonText = '加载中...'
          setTimeout(() => {
            done()
            setTimeout(() => {
              instance.confirmButtonLoading = false
            }, 0)
          }, 1000)
        } else {
          done()
        }
      },
    }).then(async () => {
      if (status != 3) {
        var arr2 = []
        tableData.value = tableData.value.map((o) => {
          if (arr.includes(o.num)) {
            o.status = status
            if (o.id) {
              arr2.push(o.id)
            }
          }
          return o
        })
        if (arr2.length > 0) {
          const res = await method(arr2, status)
          ElMessage({
            message: res.data.message,
            type: 'success',
            duration: 2000,
          })
        }
      } else {
        var arr2 = []
        tableData.value = tableData.value.filter((o) => {
          if (arr.includes(o.num)) {
            if (o.id) {
              arr2.push(o.id)
            }
          } else {
            return o
          }
        })
        if (arr2.length > 0) {
          const res = await method(arr2)
          ElMessage({
            message: res.data.message,
            type: 'success',
            duration: 2000,
          })
        }
      }
      selecttion.value = []
      // getDetail()
    })
  }

  // 批量启用/禁用/删除
  const changeStatus = (n) => {
    if (n == 1) {
      changeMethod('启用', disableVisitModuleField, selecttion.value, false)
    }
    if (n == 2) {
      changeMethod('禁用', disableVisitModuleField, selecttion.value, true)
    }
    if (n == 3) {
      changeMethod('删除', deleteVisitModuleField, selecttion.value, 3)
    }
    if (n == 4) {
      changeMethod('删除', deleteVisitModuleField, [addOrUpdateFieldModalValue.value.form.id], 3)
    }
  }

  // watch(
  //   () => route.name,
  //   (value) => {
  //     if (value === 'editTemplate' || value === 'addTemplate') {
  //       getModuleOptionsFn('')
  //       if (route.params.id) {
  //         // getDetail()
  //       }
  //     }
  //   },
  // )

  // 监听工单模块ID变化
  watch(
    () => moduleIds.value,
    (newVal) => {
      moduleTmpIds.value.forEach((item) => {
        if (!newVal.includes(item)) {
          moduleForm.value.templateModuleIds.forEach((ele) => {
            !moduleForm.value.delTemplateModuleIds && (moduleForm.value.delTemplateModuleIds = [])
            if (ele.moduleId == item && !moduleForm.value.delTemplateModuleIds.includes(ele.id)) {
              moduleForm.value.delTemplateModuleIds.push(ele.id)
            }
          })
        }
      })
    },
  )

  onMounted(() => {
    moduleIds.value = []
    moduleForm.value.id = null
    moduleForm.value.name = ''
    moduleForm.value.status = false
    getModuleOptionsFn('')
    if (route.params.id) {
      getDetail()
    }
  })
</script>

<style scoped lang="scss">
  @import './index.scss';
</style>
